﻿using ZeroSum.Domain.Repositories;
using ZeroSum.Exceptions;
using ZeroSum.Plugin.Authorization.Datas.Aggregates.UserAggregate;

namespace ZeroSum.Plugin.Authorization.Datas.Services.Users;

public class UserBaseDomainService<TUser> : IUserBaseDomainService<TUser> where TUser : UserBase
{
    protected readonly IRepository<TUser, long> UserRepository;

    public UserBaseDomainService(IRepository<TUser, long> userRepository)
    {
        UserRepository = userRepository;
    }

    public virtual async Task<TUser> AddAsync(TUser entity, CancellationToken cancellationToken = default)
    {
        await CheckUserExist(entity.Account);
        entity.NormalizeAccount = entity.Account?.ToUpper();
        return await UserRepository.AddAsync(entity);
    }

    public virtual async Task CheckUserUpdate(string? account, long id)
    {
        var isRoleExist = await UserRepository.AnyAsync(u => u.Id == id);
        if (!isRoleExist)
            throw AlreadyExistedException.Of($"编号为“{id}”的用户不存在！")!;
        var isExist =
            await UserRepository.AnyAsync(u =>
                account != null && u.NormalizeAccount == account.ToUpper() && u.Id != id);
        if (isExist)
            throw AlreadyExistedException.Of($"用户名为“{account}”的用户已存在！")!;
    }

    public virtual async Task UpdateAsync(TUser entity, CancellationToken cancellationToken = default)
    {
        await UserRepository.UpdateAsync(entity);
    }

    public virtual async Task DeleteAsync(long id, CancellationToken cancellationToken = default)
    {
        await CheckUserExist(id);
        var entity = await UserRepository.GetAsync(id);
        await UserRepository.RemoveAsync(entity);
    }

    public virtual async Task<TUser> GetByIdAsync(long id, CancellationToken cancellationToken = default)
    {
        return await UserRepository.GetAsync(id);
    }

    public virtual async Task<TUser> FirstOrDefaultAsync(IQuery<TUser> query)
    {
        return await UserRepository.GetAsync(query);
    }

    private async Task CheckUserExist(long id)
    {
        var isExist = await UserRepository.AnyAsync(u => u.Id == id);
        if (isExist)
            throw NoMatchedResultException.Of($"编号为“{id}”的用户不存在！")!;
    }

    private async Task CheckUserExist(string? account)
    {
        var isExist = await UserRepository.AnyAsync(u => account != null && u.NormalizeAccount == account.ToUpper());
        if (isExist)
            throw AlreadyExistedException.Of($"用户名为“{account}”的用户已存在！")!;
    }
}